import cv2
import mediapipe as mp
import time
import socket

import json
SERVER_IP = "192.168.1.12"
SERVER_PORT = 8888

print("Starting socket: TCP...")
server_addr = (SERVER_IP, SERVER_PORT)
socket_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # TCP

while True:
    try:
        print("Connecting to server @ %s:%d..." %(SERVER_IP, SERVER_PORT))
        socket_tcp.connect(server_addr)
        break
    except Exception:
        print("Can't connect to server,try it latter!")
        time.sleep(1)
        continue
#cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
#cap = cv2.VideoCapture(0)  #usb  cap2


# 必须指定CAP_DSHOW(Direct Show)参数初始化摄像头,否则无法使用更高分辨率
cap = cv2.VideoCapture(0)
cap2=cv2.VideoCapture(2)
#设置摄像头分辨率 cap2 为低像素
#opencv增加帧率
cap2.set(cv2.CAP_PROP_FPS, 15)
cap2.set(cv2.CAP_PROP_FRAME_WIDTH, 340)
cap2.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)
cap.set(cv2.CAP_PROP_FPS, 15)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 400)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 380)


# # 设置摄像头设备分辨率
# cap.set(cv2.CAP_PROP_FRAME_WIDTH, WIDTH)
# cap.set(cv2.CAP_PROP_FRAME_HEIGHT, HEIGHT)
# # 设置摄像头设备帧率,如不指定,默认600
# cap.set(cv2.CAP_PROP_FPS, 24)
# # 建议使用XVID编码,图像质量和文件大小比较都兼顾的方案
# #fourcc = cv2.VideoWriter_fourcc(*'XVID')

mpHands = mp.solutions.hands
print("hands",mpHands.Hands())
hands = mpHands.Hands()

mpDraw = mp.solutions.drawing_utils
# 帧率统计
pTime = 0
cTime = 0
pxssmax = []#最大17-0 x距离
pyssmax = []#最大0-9 y距离
while True:
    success, img2 = cap2.read()

    success, img = cap.read()
    img = cv2.flip(img, 1)
    imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)#转换为rgb
    results = hands.process(imgRGB)

    print(results.multi_hand_landmarks)
    if results.multi_hand_landmarks:

        for handLms in results.multi_hand_landmarks:

            py=[0,1,2,3]
            px=[0,1,2,3]
            for id, lm in enumerate(handLms.landmark):
                print(id, lm)
                # 获取手指关节点
                h, w, c = img.shape
                cx, cy ,cz= int(lm.x*w), int(lm.y*h),int(lm.z*w) #转换为像素坐标
                cv2.putText(img, str(int(id)), (cx+10, cy+10), cv2.FONT_HERSHEY_PLAIN,
                            1, (0, 0, 255), 2)
                if (id == 0):
                    py[2]=cy
                    px[2]=cx

                if(id==5):

                    px[0]=cx

                if(id == 9):
                    py[0]=cy


                if(id == 12):
                    py[1]=cy
                    px[3]=cx

                    cv2.putText(img, str(cx)+","+str(cy), (cx + 120, cy + 20), cv2.FONT_HERSHEY_PLAIN,
                                    1, (0, 0, 255), 2)
                if(id == 17):
                    px[1]=cx
                    py[3]=cy
                    cv2.putText(img, str(cx)+","+str(cy), (cx + 120, cy + 20), cv2.FONT_HERSHEY_PLAIN,
                                    1, (0, 0, 255), 2)
            yy= py[0] - py[1]   #y轴距离
            yyall= py[2] - py[1]
            yyd= py[2] - py[0]# 0-9 y
            xxw= px[1] - px[2]  #17-0 x 实际距离 注：实际距离/真实距离=偏转比例 ×90 等于偏转角度
            xd=0
            if(len(pxssmax)<30):  #前30帧记录最大值 也就是求手掌长u宽比 这里建议取平均值 当时没考虑这么多

                pxssmax.append(xxw)
                pyssmax.append(yyd)


            else:   #dddxxcc

                if(xxw>0):
                    cv2.putText(img, str(90-yyd*max(pxssmax) / max(pyssmax)) + "bi"+str(xxw)+"cc  "+str(xxw/(yyd*max(pxssmax) / max(pyssmax))*90), (60, 60),
                                cv2.FONT_HERSHEY_PLAIN,
                                1, (0, 0, 255), 2)
                    xd=90-xxw/(yyd*max(pxssmax) / max(pyssmax))*90 # 这里注意下当手掌左右翻转 0点到9点是不会变化太大 因此可以求此时手掌的17-9的长度（z轴变化会影响这个17-9的真实比例长度[手掌的远近真实大小会在图像上变化，但是偏转只能看见偏转的长度相当与三角形的短边]）
                    cv2.putText(img, str(90-xxw/(yyd*max(pxssmax) / max(pyssmax))*90) + "x", (120, 40), cv2.FONT_HERSHEY_PLAIN,
                                1, (0, 0, 255), 2)#yyd*max(pxssmax) 也就是当前z轴距离下17 - 0 x的距离 xxw 也就是肉眼看见的17-0 随着偏转角度变大 xxw变小 而 yyd不变 所以yyd×max（pxssmax）不变
                elif(xxw<0):
                    cv2.putText(img, str(90-yyd * max(pxssmax) / max(pyssmax)) + "bi" + str(xxw) + "cc  " + str(90-
                        xxw / (yyd * max(pxssmax) / max(pyssmax)) * 90), (60, 60),
                                cv2.FONT_HERSHEY_PLAIN,
                                1, (0, 0, 255), 2)
                    xd = 90-xxw / (yyd * max(pxssmax) / max(pyssmax)) * 90  # danqian x suozhan shi ji x bi
                    cv2.putText(img, str(90-xxw / (yyd * max(pxssmax) / max(pyssmax)) * 90) + "x", (120, 40),
                                cv2.FONT_HERSHEY_PLAIN,
                                1, (0, 0, 255), 2)

          #  cv2.putText(img, str(xxall) + "xxall", (80, 40), cv2.FONT_HERSHEY_PLAIN,
            #            1, (0, 0, 255), 2)
            cv2.putText(img, str(yy)+"yy", (20,20), cv2.FONT_HERSHEY_PLAIN,
                        1, (0, 0, 255), 2)
            cv2.putText(img, str(yyall)+"all", (20, 40), cv2.FONT_HERSHEY_PLAIN,
                        1, (0, 0, 255), 2)
            yd=0
            #超出边界
            if yy > 0:
                yd=90 + yy * 180 / yyall
                if yd > 180:
                    yd=180
                cv2.putText(img, str(yd), (120, 120), cv2.FONT_HERSHEY_PLAIN,
                            1, (0, 0, 255), 2)
            else:
                yd=90 + yy * 180 / yyall
                if yd < 0:
                    yd=0
                cv2.putText(img, str(yd), (120, 120), cv2.FONT_HERSHEY_PLAIN,
                            1, (0, 0, 255), 2)
            if xd>180:
                xd=180
            elif xd<0:
                xd=0

            cv2.putText(img,str(xd)+","+ str(yd), (420, 20), cv2.FONT_HERSHEY_PLAIN,
                        1, (0, 0, 255), 2)
            print("x,y",xd,yd)
            mpDraw.draw_landmarks(img, handLms, mpHands.HAND_CONNECTIONS)
            data = socket_tcp.recv(512)
            yd=180-yd
            if len(data) > 0:
                print(data)
                list = [xd,yd]
                data = json.dumps(list)
                socket_tcp.send(data.encode('utf-8'))

    # 统计屏幕帧率
    cTime = time.time()
    fps = 1 / (cTime - pTime)
    pTime = cTime
    cv2.putText(img, str(int(fps)), (10, 70), cv2.FONT_HERSHEY_PLAIN, 3, (255, 0, 255), 3)
    cv2.imshow("tou", img2)
    cv2.imshow("image", img)


    if cv2.waitKey(2) & 0xFF == 27:
        break

cap.release()
